#include"DataStruct.h"
#include "math.h"

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <windows.h>

#define PI 3.1415926
#define UNUSED(x) (void)x;
#define random(x) rand() % (x)
#define ACCELERATE_SLOWDOWN 4000
#define WIDTH_WIDGET 2000
#define HEIGHT_WIDGET 1500
#define ACCELERATE_Y 6000

//产生超时故障
void timeoutFault()
{
    Sleep(1000);
}

//产生崩溃故障
void crashFault()
{
    exit(0);
}

//随机生成故障
void randGenFault()
{
    //创建静态初始化标志
    static bool initFlag = false;
    //产生随机数种子
    if (!initFlag)
    {
        srand((int)time(NULL));
        initFlag = true;
    }
    //随机生成故障
    switch (random(3)) {
    case 0:
        timeoutFault();
    case 1:
        crashFault();
    }
}

int aim(DataStruct *data, BallStruct &ball, int &leftward, int &rightward)
{
    double x=ball.x,y=ball.y,v_x=ball.v_x,v_y=ball.v_y,cosA,sinA,v,angle_ball,angle;
    v=sqrt(v_x*v_x+v_y*v_y);
    cosA=(v_x*(data->plane1.x-x)+v_y*(data->plane1.y-y))/sqrt((data->plane1.x-x)*(data->plane1.x-x)+(data->plane1.y-y)*(data->plane1.y-y))/v;
    sinA=sqrt(1-cosA*cosA);
    angle_ball=-90-(asin(sinA*v/WIDTH_WIDGET)+atan2(data->plane1.y-y,data->plane1.x-x))*180/PI;
    angle=fmod(fmod(data->plane1.angle-angle_ball,360)+360,360);

    //根据角度差选择更优旋转方向
    if (angle < 3.6 || angle > 356.4)
    {
        return 1;
    }
    else if (angle < 180)
    {
        leftward = 1;
        rightward = 0;
    }
    else
    {
        leftward = 0;
        rightward = 1;
    }
    return 0;
}

int turn(DataStruct *data,double x,double y,int &leftward,int &rightward)
{
    double cosA,angle_aim,angle;
    cosA=(y-data->plane1.y)/sqrt((x-data->plane1.x)*(x-data->plane1.x)+(y-data->plane1.y)*(y-data->plane1.y));
    angle_aim=acos(cosA)*180/PI;
    angle=fmod(fmod(data->plane1.angle-angle_aim,360)+360,360);
    if(angle<3.6||angle>356.4)
        return 1;
    else if(angle<180)
    {
        leftward=1;
        rightward=0;
        return 0;
    }
    else
    {
        leftward=0;
        rightward=1;
        return 0;
    }
}
void location(DataStruct*data,int t,double &x,double &y)
{
    double vx0,vy0,vx1,vy1,a_x,a_y;
    vx0 = data->plane1.v_x;
    vy0 = data->plane1.v_y;
    if(vx0==0&&vy0==0)
    {
        x=data->plane1.x;
        y=data->plane1.y;
    }
    a_x=-vx0/sqrt(vx0*vx0+vy0*vy0)*ACCELERATE_SLOWDOWN;
    a_y=-vy0/sqrt(vx0*vx0+vy0*vy0)*ACCELERATE_SLOWDOWN;
    vx1=vx0+t*a_x/100;
    vy1=vy0+t*a_y/100;
    if(vx1*vx0<0)
        vx1=0;
    if(vy1*vy0<0)
        vy1=0;
    x+=(vx1*vx1-vx0*vx0)/(2*a_x);
    y+=(vy1*vy1-vy0*vy0)/(2*a_y);
//    return 0;
}
void Move(DataStruct*data,int &des_x,int &des_y,int &leftward,int &rightward,int &forward,int preTime=200)
{
    double min_t = INT_MAX;
    for (int i = 0; i < data->ball_size; i++)
    {
        BallStruct &ball = data->ball[i];
        int xflag,yflag;
        double x = ball.x, y = ball.y, v_x = ball.v_x, v_y = ball.v_y,sinA,tanB,C,l,x1,y1,radC,t,dis,loc_x,loc_y;
        sinA=fabs(x-data->plane1.x)/sqrt((x-data->plane1.x)*(x-data->plane1.x)+(y-data->plane1.y)*(y-data->plane1.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
            xflag=0;
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
            xflag=1;
        }
        if(v_y<0)
        {
            yflag=0;
        }
        else
        {
            yflag=1;
        }
        l=sqrt((x-data->plane1.x)*(x-data->plane1.x)+(y-data->plane1.y)*(y-data->plane1.y))*sin(radC);
        x1=l*cos(atan(tanB));
        y1=l*sin(atan(tanB));
        C=radC*PI*180;
        t=fabs(x1/v_x)*100;
        if(!(C>=0&&C<=90&&t<preTime))
        {
            continue;
        }
        if(l<data->plane1.r+ball.r+10&&t<min_t)//满足条件，进行移动躲避
        {
            min_t=t;
            des_x = data->plane1.x +  ball.r * x1/ l;
            des_y = data->plane1.y +  ball.r * y1/ l;
            if (des_x < data->plane1.r || des_x > 2000 - data->plane1.r)
            {
                des_x = data->plane1.x;
                if (!yflag)
                    des_y = y1+data->plane1.y + ball.r + data->plane1.r;
                else
                    des_y = y1+data->plane1.y - ball.r - data->plane1.r;
            }
            //如果y越界
            if (des_y < data->plane1.r || des_y > 1500 - data->plane1.r)
            {
                des_y = data->plane1.y;
                if (xflag)
                    des_x = x1+data->plane1.x + ball.r + data->plane1.r;
                else
                    des_x = x1+data->plane1.x - ball.r - data->plane1.r;
            }
//            dis=sqrt((des_x-data->plane1.x)*(des_x-data->plane1.x)+(des_y-data->plane1.y)*(des_y-data->plane1.y));
            location(data,3000,loc_x,loc_y);
        }
        dis=sqrt((des_x-loc_x)*(des_x-loc_x)+(des_y-loc_y)*(des_y-loc_y));
        if (turn(data,des_x,des_y,leftward,rightward))
        {
            forward=0;
        }
        if(dis>=1)
        {
            forward=1;
            leftward=0;
            rightward=0;
        }
//        return 0;
    }
//    if (min_t!=INT_MAX)
//        return 1;
//    return 0;
}
int Shield(DataStruct*data,KeyStruct*key,int PreTime=12)
{
    for (int i = 0; i < data->ball_size; i++)
    {
        BallStruct &ball = data->ball[i];
//        int xflag,yflag;
        double x = ball.x, y = ball.y, v_x = ball.v_x, v_y = ball.v_y,sinA,tanB,C,l,x1,y1,radC,t,dis,loc_x,loc_y;
        sinA=fabs(x-data->plane1.x)/sqrt((x-data->plane1.x)*(x-data->plane1.x)+(y-data->plane1.y)*(y-data->plane1.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
//            xflag=0;
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
//            xflag=1;
        }
        t=fabs(x1/v_x)*100;
        if(C>=0&&C<=3.6&&t<=PreTime&&l<(data->plane1.r+ball.r))
        {
            key->shield=1;
            std::cout<<"调用了护盾";
        }
    }
}
void ai_pve(DataStruct*data,KeyStruct*key){
    //默认不移动且恒发射子弹
//    typedef struct KeyStruct{
//        int id;
//        int forward;
//        int rotate_left;
//        int rotate_right;
//        int shoot;
//        int shield;
//    }KEYSTRUCT;
    key->forward = false;
    key->rotate_left = false;
    key->rotate_right = false;
    key->shoot = true;
    //key->shield = true;

    //创建静态移动标志
    static int  des_x, des_y;

    //标志为0则正在移动或检查发现需要移动
    Move(data,des_x,des_y,key->rotate_left, key->rotate_right,key->forward);
    Shield(data,key);
    //如果球个数不为零
    if (data->ball_size)
    {
        //瞄准零号球
        aim(data, data->ball[0], key->rotate_left, key->rotate_right);
    }
}
